﻿using System;
using System.Collections.Generic;

namespace WyUnity.Utility.Cache
{
	class SimpleLRU<T> : ILRU<T>
	{
		private readonly LinkedList<T> _linklist = new LinkedList<T>();
		private readonly int _maxitem;
		private readonly int _removeRate;
		/// <summary>
		/// 在淘汰时和过期时通知缓存字典移除缓存
		/// </summary>
		private readonly Action<LinkedListNode<T>> onRemoveNode;

		public SimpleLRU(int maxitem, int removeRate, Action<LinkedListNode<T>> onRemoveNode)
		{
			_maxitem = maxitem;
			_removeRate = removeRate;
			this.onRemoveNode = onRemoveNode;
		}
		/// <summary>
		/// 移除一个缓存项，通常在显示标记缓存过期时使用
		/// </summary>
		public virtual void Remove(LinkedListNode<T> node)
		{
			_linklist.Remove(node);
			onRemoveNode(node);
		}
		/// <summary>
		/// 标记缓存刚使用过
		/// </summary>
		public void MarkUse(LinkedListNode<T> node)
		{
			if (node.List != null)
				_linklist.Remove(node);
			_linklist.AddFirst(node);
		}
		/// <summary>
		/// 新增一个缓存项
		/// </summary>
		public LinkedListNode<T> AddNew(T value)
		{
			var n = _linklist.AddFirst(value);
			AutoKnockOut();
			return n;
		}
		/// <summary>
		/// 当容量超出最大容量时，按比例淘汰一部分
		/// </summary>
		public void AutoKnockOut()
		{
			if (_linklist.Count > _maxitem)
			{
				int n = _maxitem * _removeRate / 100;
				if (_linklist.Count < n)
				{
					return;
				}
				for (; n > 0; n--)
				{
					Remove(_linklist.Last);
				}
			}
		}

		/// <summary>
		/// 当前缓存大小
		/// </summary>
		public int Count
		{
			get { return _linklist.Count; }
		}


        public void Clear()
        {
            _linklist.Clear();
        }
    }
}